package player.entity;
import config.Item.Item;
import share.item.GridItem;
import share.position.Position;

import java.util.HashMap;
import java.util.Map;

/**
 * 仓库类 - 使用Map存储道具位置
 */
public class Repository {
    private int boxId;
    private int type;
    private int playerId;
    private int gridWidth;      // 格子宽度
    private int gridHeight;     // 格子高度

    // 使用Map存储道具位置：Key是道具ID，Value是道具对象和位置信息
    private Map<Integer, GridItem> items = new HashMap<>();

    // 格子占用状态矩阵
    private boolean[][] occupied;

    public Repository(int boxId, int type, int playerId, int width, int height) {
        this.boxId = boxId;
        this.type = type;
        this.playerId = playerId;
        this.gridWidth = width;
        this.gridHeight = height;
        this.occupied = new boolean[height][width];
    }

    /**
     * 尝试放置道具
     * @param item 道具
     * @param x 起始列坐标
     * @param y 起始行坐标
     * @return 是否成功
     */
    public boolean tryPlaceItem(Item item, int x, int y) {
        // 检查边界
        if (x < 0 || y < 0 ||
                x + item.getWidth() > gridWidth ||
                y + item.getHeight() > gridHeight) {
            return false;
        }

        // 检查是否有足够空间
        for (int i = y; i < y + item.getHeight(); i++) {
            for (int j = x; j < x + item.getWidth(); j++) {
                if (occupied[i][j]) {
                    return false;
                }
            }
        }

        // 占用格子
        for (int i = y; i < y + item.getHeight(); i++) {
            for (int j = x; j < x + item.getWidth(); j++) {
                occupied[i][j] = true;
            }
        }

        // 存储道具
        items.put(item.getId(), new GridItem(item, x, y));
        return true;
    }





    /**
     * 自动寻找可用位置放置道具
     * @param item 要放置的道具
     * @return 可用位置，如果找不到返回null
     */
    public Position findAvailablePosition(Item item) {
        // 遍历所有可能的起始位置
        for (int y = 0; y < gridHeight; y++) {
            for (int x = 0; x < gridWidth; x++) {
                // 检查当前位置是否能放下道具
                if (canPlaceItem(item, x, y)) {
                    return new Position(x, y);
                }
            }
        }
        return null; // 没有找到合适位置
    }

    /**
     * 检查道具是否能放置在指定位置
     */
    private boolean canPlaceItem(Item item, int startX, int startY) {
        // 计算结束位置
        int endX = startX + item.getWidth() - 1;
        int endY = startY + item.getHeight() - 1;

        // 检查是否超出边界
        if (endX >= gridWidth || endY >= gridHeight) {
            return false;
        }

        // 检查所有需要的格子是否空闲
        for (int y = startY; y <= endY; y++) {
            for (int x = startX; x <= endX; x++) {
                if (occupied[y][x]) {
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * 在找到的位置放置道具
     */
    public boolean placeItemAuto(Item item) {
        Position pos = findAvailablePosition(item);
        if (pos == null) {
            return false; // 没有可用位置
        }
        return placeItem(item, pos.getX(), pos.getY());
    }

    /**
     * 在指定位置放置道具
     */
    public boolean placeItem(Item item, int x, int y) {
        if (!canPlaceItem(item, x, y)) {
            return false;
        }

        // 标记格子为占用状态
        for (int i = y; i < y + item.getHeight(); i++) {
            for (int j = x; j < x + item.getWidth(); j++) {
                occupied[i][j] = true;
            }
        }

        // 存储道具信息
        items.put(item.getId(), new GridItem(item, x, y));
        return true;
    }

    /**
     * 移除道具
     */
    public Item removeItem(int itemId) {
        GridItem gridItem = items.remove(itemId);
        if (gridItem == null) {
            return null;
        }

        // 释放占用的格子
        for (int y = gridItem.getY(); y < gridItem.getY() + gridItem.getItem().getHeight(); y++) {
            for (int x = gridItem.getX(); x < gridItem.getX() + gridItem.getItem().getWidth(); x++) {
                occupied[y][x] = false;
            }
        }

        return gridItem.getItem();
    }



    /**
     * 寻找最适合的位置（最小浪费空间）
     */
    public Position findBestFitPosition(Item item) {
        Position bestPos = null;
        int minWastedSpace = Integer.MAX_VALUE;

        for (int y = 0; y < gridHeight; y++) {
            for (int x = 0; x < gridWidth; x++) {
                if (canPlaceItem(item, x, y)) {
                    // 计算放置后的剩余空间碎片
                    int wasted = calculateWastedSpace(item, x, y);
                    if (wasted < minWastedSpace) {
                        minWastedSpace = wasted;
                        bestPos = new Position(x, y);
                    }
                }
            }
        }

        return bestPos;
    }


    private int calculateWastedSpace(Item item, int x, int y) {
        int wasted = 0;
        // 简单实现：计算周围被隔离的小空间
        // 实际游戏中可以实现更复杂的评估算法
        return wasted;
    }




    /**
     * 尝试旋转道具寻找合适位置
     */
    public Position findAvailablePositionWithRotation(Item item) {
        // 先尝试原始方向
        Position pos = findAvailablePosition(item);
        if (pos != null) return pos;

        // 尝试旋转90度（宽高互换）
        Item rotated = new Item(); // TODO 道具的数据
        pos = findAvailablePosition(rotated);
        if (pos != null) {
            item.setWidth(rotated.getWidth());
            item.setHeight(rotated.getHeight());
            return pos;
        }

        return null;
    }


    // 在Repository中添加堆叠支持
    public boolean tryStackItem(Item newItem, Position position) {
        GridItem existing = getItemAt(position);
        if (existing != null && existing.getItem().canStackWith(newItem)) {
            int total = existing.getItem().getCurrentStack() + newItem.getCurrentStack();
            if (total <= existing.getItem().getMaxStack()) {
                existing.getItem().setCurrentStack(total);
                return true;
            } else {
                // 部分堆叠
                int canAdd = existing.getItem().getMaxStack() - existing.getItem().getCurrentStack();
                existing.getItem().setCurrentStack(existing.getItem().getMaxStack());
                newItem.setCurrentStack(newItem.getCurrentStack() - canAdd);
                return false; // 表示还有剩余
            }
        }
        return false;
    }
}